#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

//左值：可以进行取地址的就是左值
//右值：不能进行取地址的就是右值
void test()
{
    int a = 10;
    int b = 20;
    &a;//ok,左值可以取地址
    &b;//ok,左值可以取地址
    /* &(a + b);//error,右值不能取地址 */
    int *pInt = &a;
    &pInt;//ok,左值可以取地址
    &*pInt;//ok,左值可以取地址,稍微麻烦一些

    string s1("hello");
    string s2("wangdao");
    &s1;//ok,左值可以取地址
    &s2;//ok,左值可以取地址
    /* &(s1 + s2);//error,右值不能取地址 *1/ */
    string s3 = s1 +s2;
    &s3;//error,右值不能取地址 */
    &"hello";//位于文字常量区,可以取地址
    /* &string("hello");//error,右值不能取地址 */ 

    //引用的基本操作
    int number = 100;
    int &ref = number;//ok
    &number;//ok,左值可以取地址
    &ref;//ok,左值可以取地址
    /* &100;//error,100是右值 */
    /* int &ref2 = 100;//error,非cost左值引用不能绑定右值 */
    //const左值引用可以绑定到右值,可以绑定到左值
    const int &ref3 = 100;//ok
    const int &ref4 = number;//ok
    
    //在C++11之前，是不能识别出右值的
    //右值引用
    //右值引用不能单独存在，必须要进行初始化
    int value = 10;
    /* int &&rref = value;//error,右值引用不能绑定到左值 */
    int &&rref2 = 10;//ok,右值引用可以绑定到右值
    const int &&rref3 = 10;//ok
    /* const int &&rref4 = value;//error */
    //右值引用到底是左值还是右值？
    //右值引用既可以是左值，也可以是右值
    &rref2;
    &rref3;
}

int &&func()
{
    int number = 10;
    /* return 10;//表意上来说是没有问题的 */
    return std::move(number);
}

int main(int argc, char *argv[])
{
    test();
    /* &func(); */
    return 0;
}

